﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Runtime.InteropServices;
using SharedLib.Engine;
using Krypton;
using Krypton.Lights;
using Ruminate.GUI.Framework;
using SharedLib.UI;
using Ruminate.GUI.Content;
using Microsoft.Xna.Framework.Input;

namespace SharedLib.Network.Client
{/*
    public class ClientUser
    {
 
        public GraphicsDeviceManager graphics;
        public SpriteBatch spriteBatch;
        public GraphicsDevice device;

        public ClientAudioManager audiomanager;
        public ContentManager conmanager;
        public ClientProperties Pbag;
        public Camera2D Camera;

        Texture2D playerTexture;

        Krypton.KryptonEngine Krypton;
        float ambiant = 0.1f;
        public Texture2D lightTexture;

        public RuminateGUI gui;

        private Vector2 mouseInitClick;

        public int handle;

        public int posCenterX;
        public int posCenterY;

        public ClientUser(GraphicsDeviceManager man, ContentManager cman,Krypton.KryptonEngine kry, String IP, String playerName)
        {
            audiomanager = new ClientAudioManager();
            conmanager = cman;
            graphics = man;
            device = graphics.GraphicsDevice;
            spriteBatch = new SpriteBatch(device);
            handle = (int)kry.Game.Window.Handle;
            Camera = new Camera2D();
            Pbag = new ClientProperties(IP,playerName);
            Krypton = kry;

            Initialize();
        }

        public void Initialize()
        {
            gui = new RuminateGUI(Krypton.Game);
            gui.SetTheme(new NewTheme(conmanager, gui));
            Krypton.Initialize();
        }

        public void LoadContent()
        {
            spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
            SharedLib.Engine.Tile.LoadContent(conmanager);
            playerTexture = conmanager.Load<Texture2D>("Texture/player");
            posCenterX = graphics.PreferredBackBufferWidth / 2 - playerTexture.Width / 2;
            posCenterY = graphics.PreferredBackBufferHeight / 2 - playerTexture.Height / 2;
            lightTexture = LightTextureBuilder.CreatePointLight(graphics.GraphicsDevice, 512);


            gui.AddElement(new RadioButton(10, 170, "Group1", "Red")
            {
                OnCheck = delegate { }
            });
            gui.AddElement(new RadioButton(70, 170, "Group1", "White")
            {
                OnCheck = delegate {  }
            });
            gui.AddElement(new RadioButton(150, 170, "Group1", "Blue")
            {
                OnCheck = delegate {  }
            });
        }

        public void kryptonConfig()
        {
            Krypton.AmbientColor = Color.Lerp(new Color(10, 10, 10), new Color(250, 250, 250), ambiant);
            Krypton.SpriteBatchCompatablityEnabled = true;
            Krypton.Matrix = Camera.get_transformation(graphics.GraphicsDevice);
            Krypton.CullMode = CullMode.None;
            Krypton.Bluriness = 3;
            Krypton.LightMapPrepare();
        }

        private void UpdateKeyboard(GameTime gametime)
        {
            Vector2 nextMove = Vector2.Zero;

            if (Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.Left) || Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.Q))
                nextMove += new Vector2(-1, 0);

            if (Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.Right) || Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.D))
                nextMove += new Vector2(1, 0);

            if (Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.Up) || Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.Z))
                nextMove += new Vector2(0, -1);

            if (Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.Down) || Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.S))
                nextMove += new Vector2(0, 1);

            if (Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.LeftShift) || Helpers.Input.isHold(Microsoft.Xna.Framework.Input.Keys.RightShift))
                nextMove *= Constants.PLAYER_SPEED_MULTIPLIER;

            nextMove *= Constants.PLAYER_MOVE_MULTIPLIER;

            nextMove = Vector2.Transform(nextMove, Matrix.CreateRotationZ(-Pbag.Player.Rotation));

            if (nextMove != Vector2.Zero)
            {
                Pbag.Player.Position += nextMove;
                Pbag.ClientSender.SendMovementUpdate();
            }
        }

        private void UpdateMouse(GameTime gametime)
        {
            Rectangle rect = Krypton.Game.Window.ClientBounds;
            rect.Width += rect.X;
            rect.Height += rect.Y;
            
            float ScrollWheelChange = (float)((Helpers.Input.getLastMouseState().ScrollWheelValue -
                                  Helpers.Input.getMouse().ScrollWheelValue)) / 1200;

            if(ScrollWheelChange != 0)
                Camera.Zoom += ScrollWheelChange ;

            if (Helpers.Input.getMouse().RightButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
            {
                ClipCursor(ref rect);
                if (mouseInitClick != Vector2.Zero)
                {
                    int ecartX = Helpers.Input.getMouse().X - (int)mouseInitClick.X;
                    int width = graphics.PreferredBackBufferWidth;

                    float ecartAbs = (float)ecartX / (float)width;

                    Pbag.Player.Rotation -= ecartAbs / Constants.PLAYER_ROTATION_FOV;

                    Pbag.ClientSender.SendRotationUpdate();
                }
                
                mouseInitClick = new Vector2(Helpers.Input.getMouse().X, Helpers.Input.getMouse().Y);
            }
            else
            {
                mouseInitClick = Vector2.Zero;
                Rectangle fullSize = new Rectangle(int.MinValue / 2, int.MinValue / 2, int.MaxValue, int.MaxValue);
                ClipCursor(ref fullSize);
            }
        }

        public void Update(GameTime gameTime)
        {
            Pbag.ClientListener.Update();

            if (WindowHasFocus())
            {
                UpdateKeyboard(gameTime);
                UpdateMouse(gameTime);

                createPlayersLights();

                gui.Update();
            }
        }

        public void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.Black);


            if (Pbag.State == ClientState.Logged)
            {
                Vector2 decalPosition= new Vector2(0,Constants.PLAYER_DRAWING_DECAL);
                decalPosition = Vector2.Transform(decalPosition, Matrix.CreateRotationZ(-Pbag.Player.Rotation));
                Camera.Pos = Pbag.Player.Position - decalPosition;
                Camera.Rotation = Pbag.Player.Rotation ;

                kryptonConfig();
                
                graphics.GraphicsDevice.Clear(Color.Black);
                spriteBatch.Begin(SpriteSortMode.Immediate,
                            BlendState.AlphaBlend,
                            null,
                            null,
                            null,
                            null,
                            Camera.get_transformation(graphics.GraphicsDevice));

                drawAround();

                foreach (var item in Pbag.WorldManager.playerlist)
                {
                    spriteBatch.Draw(playerTexture, new Rectangle((int)item.Value.Position.X, (int)item.Value.Position.Y, playerTexture.Width, playerTexture.Height), new Rectangle(0, 0, playerTexture.Width, playerTexture.Height), Color.White, -item.Value.Rotation - MathHelper.PiOver2, new Vector2(playerTexture.Width / 2, playerTexture.Height / 2), SpriteEffects.None, 0f);
                }
                spriteBatch.Draw(playerTexture, new Rectangle((int)(Pbag.Player.Position.X), (int)(Pbag.Player.Position.Y), playerTexture.Width, playerTexture.Height), new Rectangle(0, 0, playerTexture.Width, playerTexture.Height), Color.White, -Pbag.Player.Rotation - MathHelper.PiOver2, new Vector2(playerTexture.Width / 2, playerTexture.Height / 2), SpriteEffects.None, 0f);
                
                spriteBatch.End();

                Krypton.Draw(gameTime);

                gui.Draw();
            }


        }



        //create hulls in player viewport
        private void createHulls()
        {
            Vector2 _position = Pbag.Player.Position;
            int caseX = (int)_position.X / Constants.TILE_SIZE;
            int caseY = (int)_position.Y / Constants.TILE_SIZE;

            int decalX = (int)_position.X % Constants.TILE_SIZE;
            int decalY = (int)_position.Y % Constants.TILE_SIZE;

            int startX = caseX - (Constants.SCREEN_WIDTH / 2);
            int startY = caseY - (Constants.SCREEN_HEIGHT / 2);

            int endX = caseX + (Constants.SCREEN_WIDTH / 2);
            int endY = caseY + (Constants.SCREEN_WIDTH / 2);

            if (startX < 0)
                startX = 0;
            if (endX > Pbag.WorldManager.Zone.Size.X - 1)
                endX = Pbag.WorldManager.Zone.Size.X - 1;

            if (startY < 0)
                startY = 0;
            if (endY > Pbag.WorldManager.Zone.Size.Y - 1)
                endY = Pbag.WorldManager.Zone.Size.Y - 1;

            Krypton.Hulls.Clear();
            for (int x = startX; x <= endX; x++)
            {
                for (int y = startY; y <= endY; y++)
                {
                    if (Pbag.WorldManager.World[x, y] == 15)
                    {
                        var hull = ShadowHull.CreateRectangle(Vector2.One);
                        hull.Position.X = x * SharedLib.Constants.TILE_SIZE;
                        hull.Position.Y = y * SharedLib.Constants.TILE_SIZE;
                        hull.Scale.X = SharedLib.Constants.TILE_SIZE;
                        hull.Scale.Y = SharedLib.Constants.TILE_SIZE;

                        Krypton.Hulls.Add(hull);
                    }
                }
            }
        }

        //draw light for each players
        private void createPlayersLights()
        {
            Krypton.Lights.Clear();
            foreach (var item in Pbag.WorldManager.playerlist)
            {
                Light2D light = new Light2D()
                {
                    Texture = lightTexture,
                    Range = 200,
                    Color = Color.White,
                    Intensity = 1f,
                    Angle = 0,

                    X = item.Value.Position.X,
                    Y = item.Value.Position.Y
                };
                Krypton.Lights.Add(light);
            }

            Light2D mylight = new Light2D()
            {
                Texture = lightTexture,
                Range = 200,
                Color = Color.White,
                Intensity = 1f,
                Angle = 0,

                X = Pbag.Player.Position.X,
                Y = Pbag.Player.Position.Y
            };
            Krypton.Lights.Add(mylight);
        }

        //draw only sprite in player viewport
        private void drawAround()
        {
            Vector2 _position = Pbag.Player.Position;
            int caseX = (int)_position.X / Constants.TILE_SIZE;
            int caseY = (int)_position.Y / Constants.TILE_SIZE;

            int decalX = (int)_position.X % Constants.TILE_SIZE;
            int decalY = (int)_position.Y % Constants.TILE_SIZE;

            int startX = caseX - (Constants.SCREEN_WIDTH / 2);
            int startY = caseY - (Constants.SCREEN_HEIGHT / 2);

            int endX = caseX + (Constants.SCREEN_WIDTH / 2);
            int endY = caseY + (Constants.SCREEN_WIDTH / 2);

            if (startX < 0)
                startX = 0;
            if (endX > Pbag.WorldManager.World.GetLength(0))
                endX = Pbag.WorldManager.World.GetLength(0);

            if (startY < 0)
                startY = 0;
            if (endY > Pbag.WorldManager.World.GetLength(1))
                endY = Pbag.WorldManager.World.GetLength(1);

            for (int x = startX; x < endX; x++)
            {
                for (int y = startY; y < endY; y++)
                {
                    spriteBatch.Draw(SharedLib.Engine.Tile.getTexture(), new Rectangle(x * SharedLib.Constants.TILE_SIZE, y * SharedLib.Constants.TILE_SIZE, SharedLib.Constants.TILE_SIZE, SharedLib.Constants.TILE_SIZE), SharedLib.Engine.Tile.getTileRectangle(Pbag.WorldManager.World[x, y]), Color.White, 0f, new Vector2(SharedLib.Constants.TILE_SIZE / 2, SharedLib.Constants.TILE_SIZE / 2), SpriteEffects.None, 0f);
                }
            }
        }

        public bool WindowHasFocus()
        {
            return GetForegroundWindow() == handle;
        }
        
        [DllImport("user32.dll")]
        public static extern int GetForegroundWindow();

        [DllImport("user32.dll")]
        static extern void ClipCursor(ref Rectangle rect);
    }*/
}
